/*
   This file is part of kleber.
   Copyright 2008 Simon Schmeisser <mail_to_wrt@gmx.de>
   
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
    
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "KleberDocument.h"

#include <podofo/podofo.h>

#if 0
#include <QtGui/QPrinter>
#endif

#include <QtGui/QPainter>
#include <QtGui/QImage>

#include <QtCore/QDebug>

#include <string>
#include <iostream>

KleberDocument::KleberDocument()
{
}

void KleberDocument::registerClass(QScriptEngine* engine)
{
	if (!engine)
		return ;
	
	QScriptValue ctor = engine->newFunction(KleberDocumentConstructor);
	QScriptValue metaObject = engine->newQMetaObject(&QObject::staticMetaObject, ctor);
	engine->globalObject().setProperty("Document", metaObject);
}


void KleberDocument::appendPage(KleberPage *page)
{
	if ( not page )
		return ;
	
	m_pages.append(page);
}

KleberPage* KleberDocument::takeFirstPage()
{
	if ( m_pages.isEmpty() ) {
		return NULL;
	}

	return m_pages.takeFirst();
}

void KleberDocument::deleteAllPages()
{
	foreach(KleberPage* page, m_pages) {
		delete page;
	}
	m_pages.clear();
}

void KleberDocument::scanAllBarcodes()
{
	// TODO: do some fancy multithreading here
	//
	foreach(KleberPage* page, m_pages) {
		page->numBarcodes();
	}
}

void KleberDocument::savePdf()
{
#if 0	
	QPrinter printer;
	
	printer.setOutputFormat(QPrinter::PdfFormat);
	printer.setPageSize(QPrinter::A4);
	printer.setOutputFileName(m_fileName);
	printer.setFullPage(true);
	
	QPainter painter(&printer);

	bool isNotFirstPage = false;
	foreach( KleberPage* page, m_pages) {
		if (isNotFirstPage)
			printer.newPage();
		else
			isNotFirstPage = true;
		
		//printer.setResolution(   ); //in dpi
		if (page->pixelWidth() > page->pixelHeight()) {
			printer.setOrientation(QPrinter::Landscape);
			qDebug() << "Landscape" << page->pixelWidth() << " " << page->pixelHeight();
		} else {
			printer.setOrientation(QPrinter::Portrait);
			qDebug() << "Portrait: " << page->pixelWidth() << " " << page->pixelHeight();
		}
		/*if (isNotFirstPage)
			printer.newPage();
		else
			isNotFirstPage = true;
		QPainter painter(&printer);*/
		painter.drawImage(QPoint(0, 0), page->image());

	}
#endif
	PoDoFo::PdfStreamedDocument document( m_fileName.toAscii() );
	/*
	* This pointer will hold the page object later. 
	* PdfSimpleWriter can write several PdfPage's to a PDF file.
	*/
	PoDoFo::PdfPage* pPage;
	/*
	* PdfPainter is the class which is able to draw text and graphics
	* directly on a PdfPage object.
	*/
	PoDoFo::PdfPainter painter;
	/*
	* A PdfFont object is required to draw text on a PdfPage using a PdfPainter.
	* PoDoFo will find the font using fontconfig on your system and embedd truetype
	* fonts automatically in the PDF file.
	*/     
	PoDoFo::PdfFont* pFont;
	
	
	foreach( KleberPage* page, m_pages) {
		
		/*
		* The PdfDocument object can be used to create new PdfPage objects.
		* The PdfPage object is owned by the PdfDocument will also be deleted automatically
		* by the PdfDocument object.
		*
		* You have to pass only one argument, i.e. the page size of the page to create.
		* There are predefined enums for some common page sizes.
		*/
		pPage = document.CreatePage( PoDoFo::PdfPage::CreateStandardPageSize( PoDoFo::ePdfPageSize_A4 ) );
		
		std::cout << pPage->GetPageSize().ToString() << "\n";
		/*
		* If the page cannot be created because of an error (e.g. ePdfError_OutOfMemory )
		* a NULL pointer is returned.
		* We check for a NULL pointer here and throw an exception using the RAISE_ERROR macro.
		* The raise error macro initializes a PdfError object with a given error code and
		* the location in the file in which the error ocurred and throws it as an exception.
		*/
		if( !pPage ) 
		{
			PODOFO_RAISE_ERROR( PoDoFo::ePdfError_InvalidHandle );
		}
		
		/*
		* Set the page as drawing target for the PdfPainter.
		* Before the painter can draw, a page has to be set first.
		*/
		painter.SetPage( pPage );
		
		/*
		* Create a PdfFont object using the font "Arial".
		* The font is found on the system using fontconfig and embedded into the
		* PDF file. If Arial is not available, a default font will be used.
		*
		* The created PdfFont will be deleted by the PdfDocument.
		*/
		pFont = document.CreateFont( "Arial" );
		
		/*
		* If the PdfFont object cannot be allocated return an error.
		*/
		if( !pFont )
		{
			PODOFO_RAISE_ERROR( PoDoFo::ePdfError_InvalidHandle );
		}
		
		/*
		* Set the font size
		*/
		pFont->SetFontSize( 18.0 );
		
		/*
		* Set the font as default font for drawing.
		* A font has to be set before you can draw text on
		* a PdfPainter.
		*/
		painter.SetFont( pFont );
		
		/*
		* You could set a different color than black to draw
		* the text.
		*
		* SAFE_OP( painter.SetColor( 1.0, 0.0, 0.0 ) );
		*/
		
		/*
		* Actually draw the line "Hello World!" on to the PdfPage at
		* the position 2cm,2cm from the top left corner. 
		* Please remember that PDF files have their origin at the 
		* bottom left corner. Therefore we substract the y coordinate 
		* from the page height.
		* 
		* The position specifies the start of the baseline of the text.
		*
		* All coordinates in PoDoFo are in PDF units.
		* You can also use PdfPainterMM which takes coordinates in 1/1000th mm.
		*
		*/
		painter.DrawText( 56.69, pPage->GetPageSize().GetHeight() - 56.69, "Hello World!" );
		
		/*
		* Tell PoDoFo that the page has been drawn completely.
		* This required to optimize drawing operations inside in PoDoFo
		* and has to be done whenever you are done with drawing a page.
		*/
		painter.FinishPage();
	
	}	
	/*
	* Set some additional information on the PDF file.
	*/
	document.GetInfo()->SetCreator ( PoDoFo::PdfString("kleber") );
	document.GetInfo()->SetAuthor  ( PoDoFo::PdfString("Simon Schmeisser") );
	document.GetInfo()->SetTitle   ( PoDoFo::PdfString("Hello World") );
	document.GetInfo()->SetSubject ( PoDoFo::PdfString("Testing the PoDoFo PDF Library") );
	document.GetInfo()->SetKeywords( PoDoFo::PdfString("Test;PDF;Hello World;") );
	
	/*
	* The last step is to close the document.
	*/
	document.Close();
	
}

void KleberDocument::setPath(const QString &path)
{
	m_path = path;
}

QString KleberDocument::path()
{
	return m_path;
}

void KleberDocument::setFileName(const QString &fileName)
{
	m_fileName = fileName;
}

QString KleberDocument::fileName()
{
	return m_fileName;
}


QScriptValue KleberDocumentConstructor(QScriptContext * context, QScriptEngine * engine)
{
	//QObject *parent = context->argument(1).toQObject();
	KleberDocument *document = new KleberDocument();//, parent);
	return engine->newQObject(document, QScriptEngine::ScriptOwnership);
}


